home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / edit / pt20pc.zip / INSCHAR.C < prev    next >
C/C++ Source or Header  |  1991-02-04  |  8KB  |  300 lines

  1. #include "pt.h"
  2.  
  3. void pascal
  4. /* XTAG:insChar */
  5. insChar(c, nlAfterCr)
  6.     unsigned char c;
  7.     int nlAfterCr;
  8. {
  9.     extern unsigned char msgBuffer[];
  10.     extern unsigned char textBuffer[];
  11.     extern struct window *selWindow;
  12.     extern long selBegin, selEnd;
  13.     extern int selMode;
  14.     extern struct window *windowList;
  15.     extern unsigned char *screenMap;
  16.     extern int scrCols;
  17.     extern int overType;
  18.     extern int autoIndent;
  19.     extern int rightMargin;
  20.     extern unsigned char scrMapReset;
  21.     extern union REGS rin, rout;
  22.     extern int unixMode;
  23.     extern int debug;
  24.  
  25.     static int insrow1, inscol1, inscol2;
  26.     static long inscp;
  27.     long cp;
  28.     long saveSelBegin, saveSelEnd;
  29.     int n, row, col;
  30.     register unsigned char ch;
  31.     unsigned char scan;
  32.     int insertPending = 0;
  33. /* CPC 4-26-88 */
  34.     int currentCol = -1;    /* horizontal char pos cache */
  35. /* CPC 4-26-88 */
  36.     
  37.     /* erase the old selection in case it covers two or more lines */
  38.     eraseSelection();
  39.  
  40.     /* selection mode is character after an insert */
  41.     selMode = SELCHAR;
  42.  
  43. nextChar:
  44.     if( c == '\177') {    /* del or Ctrl-Backspace */
  45.         cp = selBegin;
  46.         /* first scan back over white space */
  47.         while( 1 ) {
  48.             ch = readChar(selWindow->fileId, --cp);
  49.             switch( ch ) {
  50.             case ' ':
  51.             case '\t':
  52.             case '\r':
  53.             case '\n':
  54.                 break;
  55.             default:
  56.                 goto endWhite;    /* break out of while loop */
  57.             }
  58.         }
  59.     endWhite:
  60.         /* now scan over alphanumerics */
  61.         if( isalnum(ch) ) {
  62.             while( isalnum(ch) ) {
  63.                 if( cp <= 0 )
  64.                     break;
  65.                 ch = readChar(selWindow->fileId, --cp);
  66.             }
  67.         } else {
  68.             while( !isalnum(ch) && !isspace(ch) && !iscntrl(ch) ) {
  69.                 if( cp <= 0 )
  70.                     break;
  71.                 ch = readChar(selWindow->fileId, --cp);
  72.             }
  73.         }
  74.         selEnd = selBegin - 1;
  75.         selBegin = cp + 1;
  76.         if( selBegin <= selEnd ) {
  77.             if( deleteChars(selWindow->fileId, NOUPDATE, 0) )
  78.                 c = '\r'; /* if so, force a redrawWindow */
  79.         } else
  80.             selEnd = selBegin;
  81.         flush();    /* flush the input buffer */
  82.     } else if( c == '\b') {
  83.         if( selBegin > 0 ) {
  84.             if( readChar(selWindow->fileId, selBegin-1) == '\n'
  85.              || !delChar() ) {
  86.                 selEnd = --selBegin;
  87.                 if( readChar(selWindow->fileId, selBegin-1)
  88.                                 == '\r' )
  89.                     --selBegin;
  90.                 /* deleted a newline? */
  91.                 if(deleteChars(selWindow->fileId,NOUPDATE,0))
  92.                     /* if so, force a redrawWindow */
  93.                     c = '\r';
  94.             }
  95.             flush();    /* flush the input buffer */
  96.         }
  97.     } else {
  98.         /* for UNIX files only use '\n' not '\r\n' */
  99.         /* state bit 1 == 0 means it is a DOS file */
  100.         if( c != '\r' || (selWindow->state & 0x2) == 0 )
  101.             insertChar(c);
  102.         if( rightMargin < 999 && c != '\r' ) {
  103. /* CPC 4-26-88 */
  104.             if( currentCol == -1 )
  105.                 posToxy(selWindow, selBegin, &row, &col);
  106.             else
  107.                 col = currentCol;
  108. /* CPC 4-26-88 */
  109.             if( col >
  110.                  (rightMargin+selWindow->col1-selWindow->indent+1)
  111.             ) {
  112.                 saveSelBegin = selBegin;
  113.                 saveSelEnd = selEnd;
  114.                 while( 1 ) {
  115.                     ch = readChar(selWindow->fileId,
  116.                         --selBegin);
  117.                     if( ch == ' ' || ch == '\n' 
  118.                             || selBegin <= 0 )
  119.                         break;
  120.                 }
  121.                 if( ch == ' ' )
  122.                     ++selBegin;
  123.                 else
  124.                     selBegin = saveSelBegin - 1;
  125.                 /* no need to set selEnd since */
  126.                 /* insertChar does not use it */
  127.                 if( (selWindow->state & 0x2) == 0 )
  128.                     insertChar('\r');
  129.                 insertChar('\n');
  130. /* CPC 4-26-88 */
  131.                 currentCol = -1;
  132. /* CPC 4-26-88 */
  133.                 if( autoIndent )
  134.                     n = doAutoIndent();
  135.                 else
  136.                     n = 0;
  137.                 selBegin = saveSelBegin + n + 2;
  138.                 selEnd = saveSelEnd + n + 2;
  139.                 updateFile(selWindow->fileId,selBegin,0L,0);
  140.             }
  141.         }
  142.         if( c == '\r' && nlAfterCr ) {
  143.             insertChar('\n');
  144.             if( autoIndent )
  145.                 (void)doAutoIndent();
  146.         }
  147.         if( overType ) {
  148.             selEnd = selBegin;
  149.             ch = readChar(selWindow->fileId, selBegin);
  150.             if( ch == '\r' ) {
  151.                 if( readChar(selWindow->fileId, selBegin + 1)
  152.                     == '\n' )
  153.                     ++selEnd;
  154.             }
  155.             else if( ch != '\n' )
  156.                 deleteChars(selWindow->fileId, NOUPDATE, 0);
  157.         }
  158.     }
  159.     if( c == '\r' ) {
  160.         posToxy(selWindow, selBegin-2, &insrow1, &n/*dummy*/);
  161.         /* auto-scroll at the bottom of a page */
  162.         if( insrow1+1 >= selWindow->row2 ) {
  163.             n = (selWindow->row2-selWindow->row1+1)/3;
  164.             selWindow->posTopline = nextLine(selWindow->fileId,
  165.                 selWindow->posTopline, &n);
  166.             selWindow->numTopline += n;
  167.         }
  168.         /* this is to fix the problem of the very first line of */
  169.         /* a new file not updating correctly */
  170.         if( selWindow->posBotline <= 0 )
  171.             selWindow->posBotline = selBegin;
  172.         n = indentToShowSelection(-1);
  173.         updateFile(selWindow->fileId, selWindow->posTopline, 0L, 0);
  174.         if( n ) {
  175.             redrawWindow(selWindow);
  176.             return;
  177.         }
  178.     } else {
  179.         if( selBegin < selWindow->posTopline )
  180.             doGoSel(selWindow);
  181.         if( !insertPending ) {
  182.             /* set up the screen mask for the selection window */
  183.             inscp = posToxy(selWindow, selBegin, &insrow1,
  184. /* CPC 4-26-88 */
  185.                 ¤tCol);
  186. /* CPC 4-26-88 */
  187.             inscol1 = selWindow->col1 + 1;
  188.             inscol2 = selWindow->col2 - 1;
  189.             setMap(insrow1, inscol1, insrow1, inscol2, 1, 0x07);
  190.             if( selWindow != windowList ) {
  191.                 maskTop(selWindow);
  192.                 /* see if the first character of the */
  193.                 /* selection is covered by another window, */
  194.                 /* if so, top it */
  195.                 if( *(screenMap+scrCols*insrow1+currentCol)
  196.                                 == 0 ) {
  197.                     doTopWindow(selWindow, 0);
  198.                     /* do it again since the windows */
  199.                     /* have changed */
  200.                     setMap(insrow1, inscol1, insrow1,
  201.                         inscol2, 1, 0x07);
  202.                 }
  203.             }
  204.         }
  205.  
  206.         /* if we have to indent, then redraw the screen */
  207. /* CPC 4-26-88 */
  208.         if( indentToShowSelection(currentCol) ) {
  209. /* CPC 4-26-88 */
  210.             redrawWindow(selWindow);
  211.             updateScreen(selWindow->row1, selWindow->row2);
  212.             return;
  213.         }
  214.  
  215.         /* do not reset the screen map while doing this drawing */
  216.         /* this is os if the next block loops back with */
  217.         /* insertPending=1, then the "setMap" above will still */
  218.         /* be valid */
  219.         scrMapReset = 1;
  220.         fillLine(selWindow, inscp, insrow1, inscol1, inscol2);
  221.         scrMapReset = 0;
  222.         updateScreen(insrow1, insrow1);
  223.     }
  224.     /* see if another character is waiting */
  225.     if( isKeystroke() != 0 && c != '\r' ) {
  226. /* CPC 4-26-88 */
  227.         /* invalidate the column caching when you see a tab */
  228.         /* or a backspace */
  229.         if( c == '\t' || c == '\b' )
  230.             currentCol = -1;
  231.         else
  232.             ++currentCol;
  233. /* CPC 4-26-88 */
  234.         /* call BIOS keyboard handler to get the next character */
  235.         /* but do not remove it from the buffer */
  236.         c = peekKeystroke(&scan);
  237.         /* is it between a backspace and a '~'? */
  238.         /* scan test disallows the Grey keys */
  239.         if( 8 <= c && c <= 126 && scan < 56 ) {
  240.             /* remove it from the buffer */
  241.             (void)getKeystroke(&scan/*dummy*/);
  242.             insertPending = 1;
  243.             goto nextChar;
  244.         }
  245.     }
  246. }
  247.  
  248.  
  249. int pascal
  250. /* XTAG:doAutoIndent */
  251. doAutoIndent()
  252. {
  253.     extern unsigned char msgBuffer[];
  254.     extern long selBegin;
  255.     extern struct window *selWindow;
  256.  
  257.     unsigned char scan;
  258.     long cp;
  259.     int n, charsInserted;
  260.  
  261.     n = -1;
  262.     cp = prevLine(selWindow->fileId, selBegin-2, &n);
  263.     charsInserted = 0;
  264.     while( 1 ) {
  265.         scan = readChar(selWindow->fileId, cp);
  266.         switch( scan ) {
  267.             case ' ':
  268.             case '\t':
  269.                 insertChar(scan);
  270.                 ++charsInserted;
  271.                 break;
  272.             default:
  273.                 return charsInserted;
  274.         }
  275.         ++cp;
  276.     }
  277. }
  278.  
  279. void pascal
  280. /* XTAG:insAscii */
  281. insAscii()
  282. {
  283.     int i;
  284.     register unsigned char *fileName;
  285.  
  286.     fileName = getInput("Enter ASCII code (20=024=0x14): ", "", 0);
  287.     if( fileName == NULL ) {
  288.         msg("Enter ASCII cancelled, no character inserted", 1);
  289.         return;
  290.     }
  291.     if( fileName[0] == '0' && fileName[1] != '\0' ) {
  292.         if( fileName[1] == 'x' )
  293.             sscanf(&fileName[2], "%x", &i);
  294.         else
  295.             sscanf(&fileName[1], "%o", &i);
  296.     } else
  297.         sscanf(fileName, "%d", &i);
  298.     insChar((unsigned char)i, 0);    /* 0 => no NL after CR */
  299. }
  300.